using System;
using System.Collections.Generic;
using System.Text;

namespace InfiniTec.DirectoryServices
{
    /// <summary>
    /// This class implements useful helper functions for LDAP path manipulation
    /// </summary>
    public static class LdapPath
    {
        /// <summary>
        /// Gets the direct parent of the specified LDAP path
        /// </summary>
        /// <param name="ldapPath">The ldap path.</param>
        public static string GetParent(string ldapPath)
        {
            return GetParent(ldapPath, 1);
        }

        /// <summary>
        /// Gets the parent with the specified generation 
        /// of the specified LDAP path. 
        /// </summary>
        /// <param name="ldapPath">The ldap path.</param>
        /// <param name="generation">The generation.</param>
        public static string GetParent(string ldapPath, int generation)
        {
            int index = 1;
            int currentGeneration = 0;

            if (string.IsNullOrEmpty(ldapPath)) throw new ArgumentNullException("ldapPath");

            ldapPath = ldapPath.Normalize(NormalizationForm.FormD);

            while (index < ldapPath.Length && currentGeneration < generation)
            {
                if (ldapPath[index] == ',' && ldapPath[index - 1] != '\\') currentGeneration++;

                index++;
            }

            if (index < ldapPath.Length) return ldapPath.Substring(index);
            else return "";
        }

        /// <summary>
        /// Gets the canonical name of the element represented by the specified distinguished name
        /// </summary>
        /// <param name="distinguishedName">A valid distinguished name.</param>
        /// <returns></returns>
        public static string GetCanonicalName(string distinguishedName)
        {
            int length;
            int start;

            if (string.IsNullOrEmpty(distinguishedName)) throw new ArgumentNullException("distinguishedName");

            distinguishedName = distinguishedName.Normalize(NormalizationForm.FormD);

            length = 0;
            start = -1;

            while (length < distinguishedName.Length)
            {
                if (start == -1 && distinguishedName[length] == '=')
                {
                    start = length+1;
                }
                if (distinguishedName[length] == ',' && distinguishedName[length - 1] != '\\')
                {
                    break;
                }

                length++;
            }

            length -= start;

            if (length < distinguishedName.Length) return distinguishedName.Substring(start, length);
            else return "";
        }
    }
}
